Skip to content

fix(agents): await cancelled tasks in _merge_agent_run_pre_3_11 to prevent aclose() RuntimeError#5416

Open
Koushik-Salammagari wants to merge 1 commit intogoogle:mainfrom
Koushik-Salammagari:fix/parallel-agent-pre-311-aclose-error
Open

fix(agents): await cancelled tasks in _merge_agent_run_pre_3_11 to prevent aclose() RuntimeError#5416
Koushik-Salammagari wants to merge 1 commit intogoogle:mainfrom
Koushik-Salammagari:fix/parallel-agent-pre-311-aclose-error

Conversation

@Koushik-Salammagari
Copy link
Copy Markdown

Link to Issue or Description of Change

Fixes #5297

Description

On Python 3.10, ParallelAgent uses _merge_agent_run_pre_3_11 instead of
asyncio.TaskGroup. When a sub-agent raises an exception, the finally block
cancelled all internal tasks with task.cancel() but did not await them.
This left the process_an_agent coroutines still executing their own finally
blocks — which hold references to the sub-agent async generators — when
_run_async_impl subsequently called aclose() on those generators, raising:

RuntimeError: aclose(): asynchronous generator is already running

This secondary error masked the original sub-agent exception (e.g., a
Pydantic validation failure from a structured-output agent).

Fix: add await asyncio.gather(*tasks, return_exceptions=True) after
cancellation so all tasks — including their generator cleanup — complete fully
before the caller can invoke aclose() on the generators.

Changes

  • src/google/adk/agents/parallel_agent.py: one line added to _merge_agent_run_pre_3_11 finally block
  • tests/unittests/agents/test_parallel_agent.py: regression test that directly exercises _merge_agent_run_pre_3_11 with a slow generator + failing generator, then calls aclose() — without the fix this raises RuntimeError

Testing Plan

  • New test test_merge_agent_run_pre_3_11_no_aclose_error_on_failure added to tests/unittests/agents/test_parallel_agent.py
  • All 9 existing parallel agent tests continue to pass
pytest tests/unittests/agents/test_parallel_agent.py -v
======================== 9 passed in 5.46s ===========================

@adk-bot adk-bot added the core [Component] This issue is related to the core interface and implementation label Apr 20, 2026
@rohityan rohityan self-assigned this Apr 20, 2026
@rohityan
Copy link
Copy Markdown
Collaborator

Hi @Koushik-Salammagari , Thank you for your contribution through this pull request! This PR has merge conflicts that require changes from your end. Could you please rebase your branch with the latest main branch to address these? Once this is complete, please let us know so we can proceed with the review.

@rohityan rohityan added the request clarification [Status] The maintainer need clarification or more information from the author label Apr 27, 2026
…event aclose() RuntimeError

On Python 3.10, ParallelAgent uses _merge_agent_run_pre_3_11 instead of
asyncio.TaskGroup. When a sub-agent raises, the finally block cancelled
all tasks but did not await them. This left the internal process_an_agent
coroutines still executing their own finally blocks (which hold references
to the sub-agent async generators) when _run_async_impl subsequently called
aclose() on those generators, raising:

  RuntimeError: aclose(): asynchronous generator is already running

Fix: add asyncio.gather(*tasks, return_exceptions=True) after cancellation
so that all tasks — and their generator cleanup — complete before the caller
can invoke aclose().

Fixes google#5297
@Koushik-Salammagari Koushik-Salammagari force-pushed the fix/parallel-agent-pre-311-aclose-error branch from 161742f to d5557e2 Compare April 28, 2026 18:52
@Koushik-Salammagari
Copy link
Copy Markdown
Author

Hi @rohityan, rebased the branch onto the latest main, merge conflicts are resolved. Ready for review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core [Component] This issue is related to the core interface and implementation request clarification [Status] The maintainer need clarification or more information from the author

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ParallelAgent on Python 3.10 can raise RuntimeError: aclose(): asynchronous generator is already running after one sub-agent fails

3 participants